package service

import (
	"fmt"
	"math"
	"strings"
	"usplatformserver/internal/model"
)

var (
	heartMaxRow = 8
	heartMaxCol = 8
)

var artiStatDetailSheetHeaders = []string{
	"检查号", "检查时间", "检查部位", "文件路径", "复核结果", "备注",
}

// 获取人工判读统计
func (svc *Service) GetArtificialStatistics(organType int, beginTime, endTime string) (*model.ArtificialCheckedStc, error) {
	//重组起始时间
	strBegin := fmt.Sprintf("%v 00:00:00", beginTime)
	//重组结束时间
	strEnd := fmt.Sprintf("%v 23:59:59", endTime)
	if organType == model.CheckpointThyroid {
		return svc.dao.GetThyroidArtiStatistics(strBegin, strEnd)
	} else if organType == model.CheckpointBreast {
		return svc.dao.GetBreastArtiStatistics(strBegin, strEnd)
	} else if organType == model.CheckpointCarotid {
		return svc.dao.GetCarotidArtiStatistics(strBegin, strEnd)
	}
	return nil, nil
}

func (svc *Service) GetHeartArtificialStatistics(beginTime, endTime string) ([][]int, error) {
	//重组起始时间
	strBegin := fmt.Sprintf("%v 00:00:00", beginTime)
	//重组结束时间
	strEnd := fmt.Sprintf("%v 23:59:59", endTime)
	//获取数据
	data, err := svc.dao.GetHeartArtiStatistics(strBegin, strEnd)

	//创建一个heartMaxRow*heartMaxCol的二维切片
	var arr [][]int = make([][]int, heartMaxRow)
	for i := range arr {
		arr[i] = make([]int, heartMaxCol)
	}

	if err != nil {
		return arr, err
	}

	var LVEFSet = map[int]float32{}
	pId := -1
	si := 0
	ei := 0
	for i, v := range data {
		fmt.Println("patientId: ", v.PatientId, " si: ", v.Si, " ei: ", v.Ei, " lvef: ", v.LVEF)
		if pId != v.PatientId {
			row, col := findIndex(si, ei, LVEFSet)
			fmt.Println("row: ", row, " column: ", col)
			if row >= 0 && col >= 0 {
				arr[row][col] += 1
				//行合计+1
				arr[row][heartMaxCol-1] += 1
				//列合计+1
				arr[heartMaxRow-1][col] += 1
				//总合计+1
				arr[heartMaxRow-1][heartMaxCol-1] += 1
			}
			LVEFSet = make(map[int]float32) //清空map
		}
		pId = v.PatientId
		LVEFSet[v.ChamberType] = v.LVEF * 100
		if v.LVEFSimpson > 0.001 {
			LVEFSet[model.ChamberTypeDD] = v.LVEFSimpson * 100
		}
		si = v.Si
		ei = v.Ei
		if i == len(data)-1 { //到达元素最后一个值，需要再计算一次
			row, col := findIndex(si, ei, LVEFSet)
			fmt.Println("row: ", row, " column: ", col)
			if row >= 0 && col >= 0 {
				arr[row][col] += 1
				//行合计+1
				arr[row][heartMaxCol-1] += 1
				//列合计+1
				arr[heartMaxRow-1][col] += 1
				//总合计+1
				arr[heartMaxRow-1][heartMaxCol-1] += 1
			}
		}
	}
	return arr, nil
}

func (svc *Service) GetHeartArtificialStatistics2(beginTime, endTime string) (*model.HeartAttificialCheckedStc2, error) {
	//重组起始时间
	strBegin := fmt.Sprintf("%v 00:00:00", beginTime)
	//重组结束时间
	strEnd := fmt.Sprintf("%v 23:59:59", endTime)
	//获取数据
	data, err := svc.dao.GetHeartArtiStatistics2(strBegin, strEnd)

	if err != nil {
		return nil, err
	}

	hacs := new(model.HeartAttificialCheckedStc2)

	var LVEFSet = map[int]float32{}
	pId := -1
	si := 0
	for i, v := range data {
		fmt.Println("patientId: ", v.PatientId, " si: ", v.Si, " ei: ", v.Ei, " lvef: ", v.LVEF)
		if pId != v.PatientId {
			ew5, ew10, ew15, ee15 := calcErrorCount(float32(si)/float32(100.0), LVEFSet)
			hacs.ErrorWithin5 += ew5
			hacs.ErrorWithin10 += ew10
			hacs.ErrorWithin15 += ew15
			hacs.ErrorExceeds15 += ee15
			hacs.CheckedCount += 1

			LVEFSet = make(map[int]float32) //清空map
		}
		pId = v.PatientId
		LVEFSet[v.ChamberType] = v.LVEF
		if v.LVEFSimpson > 0.001 {
			LVEFSet[model.ChamberTypeDD] = v.LVEFSimpson
		}
		si = v.Si
		if i == len(data)-1 { //到达元素最后一个值，需要再计算一次
			ew5, ew10, ew15, ee15 := calcErrorCount(float32(si)/float32(100.0), LVEFSet)
			hacs.ErrorWithin5 += ew5
			hacs.ErrorWithin10 += ew10
			hacs.ErrorWithin15 += ew15
			hacs.ErrorExceeds15 += ee15
		}
	}
	if hacs.CheckedCount > 0 {
		hacs.QualificationRate = float32(hacs.ErrorWithin10+hacs.ErrorWithin5) / float32(hacs.CheckedCount)
	}

	return hacs, nil
}

func (svc *Service) GetArtificialStatisticsDetail(beginTime, endTime string) ([]*model.ArtificialCheckedDetail, error) {
	//重组起始时间
	strBegin := fmt.Sprintf("%v 00:00:00", beginTime)
	//重组结束时间
	strEnd := fmt.Sprintf("%v 23:59:59", endTime)

	data, err := svc.dao.GetArtiStatisticsDetail(strBegin, strEnd)
	if err != nil {
		return data, err
	}
	fileNames, err := svc.dao.GetPatientRecordName(strBegin, strEnd)
	if err != nil {
		return data, err
	}

	for k, v := range data {
		for i := 0; i < len(fileNames); {
			fmt.Println("patientID: ", v.ID, "fileType: ", fileNames[i].FileType)
			if v.ID == fileNames[i].ID && v.OrganType == fileNames[i].OrganType && strings.Contains(fileNames[i].FileType, getCheckTypeText(v.OrganType)) {
				if len(data[k].FileName) == 0 {
					data[k].FileName = fileNames[i].FileNames
				} else {
					data[k].FileName += fmt.Sprintf(";%v", fileNames[i].FileNames)
				}
				fileNames = append(fileNames[:i], fileNames[i+1:]...)
			} else {
				i++
			}
		}
	}
	return data, nil
}

func findIndex(si, ei int, LVEFSet map[int]float32) (int, int) {
	//统计各阶段值，先通过人工判读区间确定行，再通过AI计算结果确定列
	row := findRow(si, ei)
	col := -1
	//M型有PLV
	lvef, exists := LVEFSet[model.ChamberTypePLV]
	if exists {
		col = findColumn(lvef)
	} else {
		//双平面法取值
		lvef, exists = LVEFSet[model.ChamberTypeDD]
		if exists {
			col = findColumn(lvef)
		} else {
			for _, lvef = range LVEFSet {
				col = findColumn(lvef)
				if col >= 0 {
					break
				}
			}
		}
	}
	return row, col
}

func findRow(si, ei int) int {
	if si == 30 && ei == 30 {
		return 0
	} else if si == 30 && ei == 40 {
		return 1
	} else if si == 40 && ei == 50 {
		return 2
	} else if si == 50 && ei == 60 {
		return 3
	} else if si == 60 && ei == 70 {
		return 4
	} else if si == 70 && ei == 80 {
		return 5
	} else if si == 80 && ei == 80 {
		return 6
	}
	return -1
}

func findColumn(lvef float32) int {
	if lvef <= 30 {
		return 0
	} else if lvef > 30 && lvef <= 40 {
		return 1
	} else if lvef > 40 && lvef <= 50 {
		return 2
	} else if lvef > 50 && lvef <= 60 {
		return 3
	} else if lvef > 60 && lvef <= 70 {
		return 4
	} else if lvef > 70 && lvef <= 80 {
		return 5
	} else if lvef > 80 {
		return 6
	}
	return -1
}

func calcErrorCount(si float32, LVEFSet map[int]float32) (uint32, uint32, uint32, uint32) {
	fmt.Println(LVEFSet, si)
	if len(LVEFSet) == 0 {
		return 0, 0, 0, 0
	}
	//辛普森>A4C>A2C>PLV>A3C
	if lvef, exists := LVEFSet[model.ChamberTypeDD]; exists {
		return calcErrorCount2(si, lvef)
	}
	if lvef, exists := LVEFSet[model.ChamberType4]; exists {
		return calcErrorCount2(si, lvef)
	}
	if lvef, exists := LVEFSet[model.ChamberType2]; exists {
		return calcErrorCount2(si, lvef)
	}
	if lvef, exists := LVEFSet[model.ChamberTypePLV]; exists {
		return calcErrorCount2(si, lvef)
	}
	if lvef, exists := LVEFSet[model.ChamberType3]; exists {
		return calcErrorCount2(si, lvef)
	}
	return 0, 0, 0, 0
}

func calcErrorCount2(si, lvef float32) (uint32, uint32, uint32, uint32) {
	var ew5 uint32 = 0
	var ew10 uint32 = 0
	var ew15 uint32 = 0
	var ee15 uint32 = 0
	if math.Abs(float64(lvef)-float64(si)) <= 0.05 {
		ew5 += 1
	}
	if math.Abs(float64(lvef)-float64(si)) <= 0.10 && math.Abs(float64(lvef)-float64(si)) > 0.05 {
		ew10 += 1
	}
	if math.Abs(float64(lvef)-float64(si)) <= 0.15 && math.Abs(float64(lvef)-float64(si)) > 0.10 {
		ew15 += 1
	}
	if math.Abs(float64(lvef)-float64(si)) > 0.15 {
		ee15 += 1
	}

	return ew5, ew10, ew15, ee15
}

func getCheckTypeText(organType int) string {
	switch organType {
	case model.CheckpointThyroid:
		return "thyroid"
	case model.CheckpointBreast:
		return "breast"
	case model.CheckpointCarotid:
		return "carotid"
	case model.CheckpointHeart:
		return "cardiac"
	default:
		return "others"
	}
}
